import { InfiniteScrollViewCpnt } from "./InfiniteScrollViewCpnt";

const { ccclass, property } = cc._decorator;

type DateType = `Year` | `Month` | `Day`

/**
 * 日期选择组件
 */
@ccclass
export class ChooseDateSvCpnt extends cc.Component {
    @property(cc.Node)
    ndBtnBg: cc.Node = null
    @property(cc.Node)
    ndCtn: cc.Node = null
    @property(cc.Node)
    ndInfiniteScrollViewCpntCtn: cc.Node = null
    @property(cc.Prefab)
    pfbInfiniteScrollViewCpnt: cc.Prefab = null
    @property(cc.Node)
    ndItem: cc.Node = null

    private _year: number;
    private _month: number;
    private _day: number;
    private _oYear: number;
    private _oMonth: number;
    private _oDay: number;
    ndYearSvCtn: cc.Node;
    ndMonthSvCtn: cc.Node;
    ndDaySvCtn: cc.Node;
    lotCtn: cc.Layout;
    svYear: InfiniteScrollViewCpnt;
    svMonth: InfiniteScrollViewCpnt;
    svDay: InfiniteScrollViewCpnt;
    private _isShow: boolean;

    onLoad() {
        cc.log(`${cc.js.getClassName(this)} onLoad`)

        this.ndInfiniteScrollViewCpntCtn.parent = null
        this.ndItem.parent = null
        // this.ndItem.getChildByName(`spSelected`).active = false
        let nowDate = new Date()
        this._year = nowDate.getFullYear()
        this._month = nowDate.getMonth() + 1
        this._day = nowDate.getDate()
        let oDate = new Date(0)
        this._oYear = oDate.getFullYear()
        this._oMonth = oDate.getMonth() + 1
        this._oDay = oDate.getDate()

        // year
        this.ndYearSvCtn = cc.instantiate(this.ndInfiniteScrollViewCpntCtn)
        this.ndCtn.addChild(this.ndYearSvCtn)

        // month
        this.ndMonthSvCtn = cc.instantiate(this.ndInfiniteScrollViewCpntCtn)
        this.ndCtn.addChild(this.ndMonthSvCtn)

        // day
        this.ndDaySvCtn = cc.instantiate(this.ndInfiniteScrollViewCpntCtn)
        this.ndCtn.addChild(this.ndDaySvCtn)

        this.lotCtn = this.ndCtn.getComponent(cc.Layout)
        this.lotCtn.updateLayout()

        // year
        this.svYear = cc.instantiate(this.pfbInfiniteScrollViewCpnt).getComponent(this.pfbInfiniteScrollViewCpnt.name)
        this.ndYearSvCtn.addChild(this.svYear.node)
        this.svYear.setItemSpace(3)
        this.svYear.setMode(`Select`, this._selectCall.bind(this))
        this.svYear.init(this._year - this._oYear + 1, this._updateCallY.bind(this), this._activeCallY.bind(this))

        // month
        this.svMonth = cc.instantiate(this.pfbInfiniteScrollViewCpnt).getComponent(this.pfbInfiniteScrollViewCpnt.name)
        this.ndMonthSvCtn.addChild(this.svMonth.node)
        this.svMonth.setItemSpace(3)
        this.svMonth.setMode(`Select`, this._selectCall.bind(this))
        this.svMonth.init(12, this._updateCallM.bind(this), this._activeCallM.bind(this))

        // day
        this.svDay = cc.instantiate(this.pfbInfiniteScrollViewCpnt).getComponent(this.pfbInfiniteScrollViewCpnt.name)
        this.ndDaySvCtn.addChild(this.svDay.node)
        this.svDay.setItemSpace(3)
        this.svDay.setMode(`Select`, this._selectCall.bind(this))
        this.svDay.init(this._getMonthTotalDay(this._year, this._month), this._updateCallD.bind(this), this._activeCallD.bind(this))
    }

    // ====================================================================================
    // ===================================== 内部接口 ======================================
    // ====================================================================================

    /**
     * 获取指定年月的总天数
     * @param year 年
     * @param month 月
     */
    private _getMonthTotalDay(year: number, month: number) {
        cc.log(`${cc.js.getClassName(this)} _getMonthTotalDay year = ${year} month = ${month}`)

        let d = new Date(year, month, 0)
        return d.getDate()
    }

    /**
     * 滑动节点选择回调
     * @param item 节点
     * @param index 节点索引
     * @param isSelect 是否选择
     * @param isSelected 是否最终选择
     */
    private _selectCall(item: cc.Node & { dateType?: DateType }, index: number, isSelect: boolean, isSelected: boolean) {
        // cc.log(`${cc.js.getClassName(this)} _selectCall index = ${index}`)
        cc.find(`lab`, item).color = isSelect ? cc.Color.BLACK : cc.Color.GRAY
        // cc.find(`spSelected`, item).active = isSelect
        if (isSelected) {
            let dateType = item.dateType
            switch (dateType) {
                case `Year`:
                    let tempYear = index + this._oYear
                    if (this._year !== tempYear) {
                        this._year = tempYear
                        this.svDay && this.svDay.init(this._getMonthTotalDay(this._year, this._month), this._updateCallD.bind(this), this._activeCallD.bind(this))
                    }

                    break
                case `Month`:
                    let tempMonth = index + 1
                    if (this._month !== tempMonth) {
                        this._month = tempMonth
                        this.svDay && this.svDay.init(this._getMonthTotalDay(this._year, this._month), this._updateCallD.bind(this), this._activeCallD.bind(this))
                    }

                    break
                case `Day`:
                    let tempDay = index + 1
                    if (this._day !== tempDay) {
                        this._day = tempDay
                    }

                    break

                default:
                    cc.error(`${cc.js.getClassName(this)} The dateType"${dateType}" is unknown!`)

                    break
            }
        }
    }


    /**
     * 滑动节点创建回调
     * @param index 节点索引
     */
    private _updateCallY(index: number): { item: cc.Node & { dateType?: DateType; }; poolName: string; } {
        // cc.log(`${cc.js.getClassName(this)} _updateCallY index = ${index}`)

        let item: cc.Node & { dateType?: DateType } = this.svYear.getItemFromPoolWithName(this.ndItem.name) || cc.instantiate(this.ndItem)
        item.getChildByName(`lab`).getComponent(cc.Label).string = `${index + this._oYear}`
        item.dateType = `Year`

        return {
            item: item,
            poolName: item.name,
        }
    }

    /**
     * 滑动节点装载或卸载回调
     * @param item 节点
     * @param index 节点索引
     * @param isActive 是否显示状态
     */
    private _activeCallY(item: cc.Node, index: number, isActive: boolean) {
        // cc.log(`${cc.js.getClassName(this)} _activeCallY index = ${index} isActive = ${isActive}`)

    }

    /**
     * 滑动节点创建回调
     * @param index 节点索引
     */
    private _updateCallM(index: number): { item: cc.Node & { dateType?: DateType; }; poolName: string; } {
        // cc.log(`${cc.js.getClassName(this)} _updateCallM index = ${index}`)

        let item: cc.Node & { dateType?: DateType } = this.svMonth.getItemFromPoolWithName(this.ndItem.name) || cc.instantiate(this.ndItem)
        item.getChildByName(`lab`).getComponent(cc.Label).string = `${index + 1}`
        item.dateType = `Month`
        return {
            item: item,
            poolName: item.name,
        }
    }

    /**
     * 滑动节点装载或卸载回调
     * @param {cc.Node} item 节点
     * @param {Number} index 节点索引
     * @param {Boolean} isActive 是否显示状态
     */
    private _activeCallM(item: cc.Node, index: number, isActive: boolean) {
        // cc.log(`${cc.js.getClassName(this)} _activeCallM index = ${index} isActive = ${isActive}`)

    }

    /**
     * 滑动节点创建回调
     * @param {Number} index 节点索引
     */
    private _updateCallD(index) {
        // cc.log(`${cc.js.getClassName(this)} _updateCallD index = ${index}`)

        let item: cc.Node & { dateType?: DateType } = this.svDay.getItemFromPoolWithName(this.ndItem.name) || cc.instantiate(this.ndItem)
        item.getChildByName(`lab`).getComponent(cc.Label).string = `${index + 1}`
        item.dateType = `Day`

        return {
            item: item,
            poolName: item.name,
        }
    }

    /**
     * 滑动节点装载或卸载回调
     * @param {cc.Node} item 节点
     * @param {Number} index 节点索引
     * @param {Boolean} isActive 是否显示状态
     */
    private _activeCallD(item: cc.Node, index: number, isActive: boolean) {
        // cc.log(`${cc.js.getClassName(this)} _activeCallD index = ${index} isActive = ${isActive}`)

    }

    // ====================================================================================
    // ===================================== 外部接口 ======================================
    // ====================================================================================

    /**
     * 切换显示
     */
    switchActive() {
        // cc.log(`${cc.js.getClassName(this)} switchActive`)

        this._isShow = !this._isShow
        this.node.active = this._isShow

        return this._isShow
    }

    /**
     * 显示
     */
    show() {
        // cc.log(`${cc.js.getClassName(this)} show`)

        this.node.active = true
        this._isShow = true

        return this._isShow
    }

    /**
     * 隐藏
     */
    hide() {
        // cc.log(`${cc.js.getClassName(this)} hide`)

        this.node.active = false
        this._isShow = false

        return this._isShow
    }

    /**
     * @returns 当前礼物列表显示状态
     */
    isShow() {
        // cc.log(`${cc.js.getClassName(this)} isShow`)

        return this._isShow
    }

    /**
     * 设置日期
     * @param year 年
     * @param month 月
     * @param day 日
     */
    setDate(year: number, month: number, day: number) {
        cc.log(`${cc.js.getClassName(this)} setDate year = ${year} month = ${month} day = ${day}`)

        this._year = year
        this._month = month
        this._day = day
    }

    // 获取日期
    getDate() {
        cc.log(`${cc.js.getClassName(this)} getDate year = ${this._year} month = ${this._month} day = ${this._day}`)

        return new Date(this._year, this._month - 1, this._day, 8, 0, 0, 1)
    }

    bindEventClose(call: () => void) {
        // cc.log(`${cc.js.getClassName(this)} bindEventClose`)

        this.ndBtnBg.targetOff(this)
        this.ndBtnBg.on(cc.Node.EventType.TOUCH_END, (event: cc.Event) => {

            call && call()
            this.hide()
        }, this)
    }
}